/** @file session_socket.h
  *
  * @brief This file contains the artosyn rpc socket node function defines.
  * Waiting for move daemon here.
  *
  *  Copyright (C) 2024, Artosyn Technologies. ALL RIGHTS RESERVED.
  *
  *  This Information is proprietary to Artosyn Technologies and MAY NOT
  *  be copied by any method or incorporated into another program without
  *  the express written consent of Artosyn. This Information or any portion
  *  thereof remains the property of Artosyn. The Information contained herein
  *  is believed to be accurate and Artosyn assumes no responsibility or
  *  liability for its use in any way and conveys no license or title under
  *  any patent or copyright and makes no representation or warranty that this
  *  Information is free from patent or copyright infringement.
  *
  */
#ifndef __SESSION_SOCKET_H__
#define __SESSION_SOCKET_H__

#include <linux/kernel.h>
#include <linux/netdevice.h>
#include "oal_main.h"

/** BB socket session tx status */
typedef enum _bb_socket_session_tx_status {
  BB_SOCKET_SESSION_TX_STATUS_IDLE,
  BB_SOCKET_SESSION_TX_STATUS_SENDING,
  BB_SOCKET_SESSION_TX_STATUS_WAIT_FOR_ACK,
  BB_SOCKET_SESSION_TX_STATUS_ACK_DONE,
  BB_SOCKET_SESSION_TX_STATUS_MAX
} bb_socket_session_tx_status;

struct socket_msg_ret {
  uint64_t pos;
  uint32_t len;
};

/** BB socket session info */
typedef struct ar_socket_session_s {
    struct list_head list;
    u8 slot;
    u32 port;
    u32 flags;
    u32 tx_buf_size;
    u32 rx_buf_size;

    /** socket rpc info */
    int work_id;
    uint64_t buf_wr_index;

    bb_socket_session_tx_status tx_status;
    int ack_sta;
    struct socket_msg_ret retmsg;
    wait_queue_head_t wait_q;                          /** For socket ack inform */

    /** ar socket rpc */
    struct sk_buff_head socket_tx_pkt_list;            /** skb list for socket tx path */
    void *socket_tx_workqueue;                         /** refers to oal_workqueue */
} ar_socket_session_t;

/**
 * @brief Create a socket seesion to ar8030
 *
 * @param   handle  Point to the oal_handle
 * @param   slot    slot of the bb socket
 * @param   port    port of the bb socket
 * @param   flag    flag of the bb socket
 *
 * @return  BB socket session structure.
 */
ar_socket_session_t* create_socket_session(oal_handle *handle, int slot, int port, int flg);

/**
 * @brief Remobe a socket seesion to ar8030
 *
 * @param   handle  Point to the oal_handle
 * @param   socket  BB socket session info
 *
 * @return  N/A.
 */
void remove_socket_session(oal_handle *handle, ar_socket_session_t* socket);

/**
 * @brief Assemble the bb socket open msg to 8030
 *
 * @param   handle          Point to the oal_handle
 * @param   slot            slot of the bb socket
 * @param   port            port of the bb socket
 * @param   flg             flag of the bb socket
 * @param   tx_buf_size     tx_buf_size of the bb socket
 * @param   rx_buf_size     rx_buf_size of the bb socket
 *
 * @return  0 for success, otherwise fail.
 */
int ar_bb_rpc_socket_open(oal_handle* handle, u8 slot, u32 port, u32 flg, u32 tx_buf_size, u32 rx_buf_size);

/**
 * @brief Assemble the bb socket close msg to 8030
 *
 * @param   handle          Point to the oal_handle
 * @param   slot            slot of the bb socket
 * @param   port            port of the bb socket
 * @param   flg             flag of the bb socket
 *
 * @return  0 for success, otherwise fail.
 */
int ar_rpc_socket_close(oal_handle* handle, u8 slot, u32 port, u32 flg);

/**
 * @brief Assemble the bb socket write skb, if there's no enough
 * skb headroom/tailroom, realloc the skb.
 *
 * @param   handle          Point to the oal_handle
 * @param   slot            slot of the bb socket
 * @param   port            port of the bb socket
 * @param   skb             skb of the data
 * @param   datagram_mode   Whether send as datagram mode
 * @param   priv_data       private data for tx callback
 * @param   timeout         timeout of the operation
 *
 * @return  0 for success, otherwise fail.
 */
int ar_rpc_socket_write(oal_handle* handle, u8 slot, u32 port, struct sk_buff *skb, bool datagram_mode, void *priv_data, int timeout);

/**
 * @brief  Push pkt to the skb queue of the socket rpc tx.
 *
 *  @param handle   Point to the oal_handle
 *  @param   slot            slot of the bb socket
 *  @param   port            port of the bb socket
 *  @param   skb             skb of the data
 *  @param   priv            private data
 *
 *  @return         N/A
 */
int
ar_rpc_socket_tx(oal_handle *handle, u8 slot, u32 port, struct sk_buff *skb, bool datagram_mode, void* priv);

/**
 * @brief Init the rpc socket.
 *
 * @param   handle          Point to the oal_handle
 *
 * @return  0 for success, otherwise fail.
 */
int
ar_rpc_socket_init(oal_handle* handle);

/**
 * @brief Deinit the rpc socket.
 *
 * @param   handle          Point to the oal_handle
 *
 * @return  N/A
 */
void
ar_rpc_socket_deinit(oal_handle* handle);


/**
 * @brief Inform the socket session when receiving the tx ack
 *
 * @param   handle  Point to the oal_handle
 * @param   slot    slot of the bb socket
 * @param   port    port of the bb socket
 * @param   sta     return value
 * @param   retmsg  return msg
 *
 * @return  N/A
 */
void socket_tx_ack_inform(oal_handle *handle, int slot, int port, int sta, struct socket_msg_ret *retmsg);

#endif
